package com.l2jserver.gameserver.communitybbs.Manager;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javolution.util.FastMap;

import com.l2jserver.Config;
import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.communitybbs.Model.BaseBBSManager;
import com.l2jserver.gameserver.datatables.MultiSell;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.instancemanager.SiegeManager;
import com.l2jserver.gameserver.instancemanager.TownManager;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.base.ClassId;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.util.StringUtil;

/**
 * @author fissban
 */
public class FavoriteBBSManager extends BaseBBSManager
{
	// Aux de clase
	private Map<Integer, String> classList;
	
	public FavoriteBBSManager()
	{
		createClassList();
	}
	
	@Override
	public void parseCmd(String command, L2PcInstance activeChar)
	{
		String content = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/index.htm");
		if (content == null)
		{
			content = "<html><body><br><br><center>404 :File not found: 'data/html/CommunityBoard/custom/favorite/index.htm' </center></body></html>";
			separateAndSend(content, activeChar);
			return;
		}
		content = content.replaceAll("%top%", topHtml());
		
		if (command.equals("_bbsgetfav"))
		{
			content = content.replaceAll("%body%", "");
			separateAndSend(content, activeChar);
			return;
		}
		if (command.startsWith("_bbsgetfav;"))
		{
			StringTokenizer st = new StringTokenizer(command, ";");
			st.nextToken();// _bbsgetfav
			
			switch (st.nextToken())
			{
				case "shop":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_SHOP_PEACE_ZONE))
					{
						return;
					}
					
					final String gmShop = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/gmShop_index.htm");
					content = content.replaceAll("%body%", gmShop);
					
					separateAndSend(content, activeChar);
					// visualizacion del multisell
					if (st.hasMoreTokens())
					{
						activeChar.setUsingCommunity(true);
						MultiSell.getInstance().separateAndSend(Integer.valueOf(st.nextToken()), activeChar, null, false);
					}
					break;
				case "class":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_CLASS_MASTER_PEACE_ZONE))
					{
						return;
					}
					
					if (!st.hasMoreTokens())
					{
						final String classMaster = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/ClassMaster_index.htm");
						content = content.replaceAll("%body%", classMaster);
					}
					else
					{
						content = content.replaceAll("%body%", classHtmlChangeClass(activeChar, Integer.parseInt(st.nextToken())));
					}
					separateAndSend(content, activeChar);
					break;
				case "change_class":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_CLASS_MASTER_PEACE_ZONE))
					{
						return;
					}
					
					final int val = Integer.valueOf(st.nextToken());
					
					if (checkAndChangeClass(activeChar, val))
					{
						content = content.replaceAll("%body%", changeClassOk(val));
					}
					separateAndSend(content, activeChar);
					break;
				case "gk":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_GK_PEACE_ZONE))
					{
						return;
					}
					
					final String gkGlobal = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/GkGlobal_index.htm");
					
					content = content.replaceAll("%body%", gkGlobal);
					if (st.hasMoreTokens())
					{
						final int x = Integer.parseInt(st.nextToken());
						final int y = Integer.parseInt(st.nextToken());
						final int z = Integer.parseInt(st.nextToken());
						doTeleport(activeChar, x, y, z);
					}
					separateAndSend(content, activeChar);
					break;
				case "gk_special":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_GK_PEACE_ZONE))
					{
						return;
					}
					
					final String gk = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/GkGlobal_index.htm");
					content = content.replaceAll("%body%", gk);
					separateAndSend(content, activeChar);
					
					String city = st.nextToken();
					final NpcHtmlMessage html = new NpcHtmlMessage(0);
					html.setFile(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/Gk" + city + "_index.htm");
					html.replace("%city%", city);
					activeChar.sendPacket(html);
					
					break;
				case "buffer":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_BUFFER_PEACE_ZONE))
					{
						return;
					}
					
					final String buffer = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/Buffer_index.htm");
					content = content.replaceAll("%body%", buffer);
					
					switch (st.nextToken())
					{
						case "Prophet":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_PROPHET, "Prophet"));
							break;
						case "Elder":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_ELDER, "Elder"));
							break;
						case "ShillienElder":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_S_ELDER, "ShillienElder"));
							break;
						case "Overlord":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_OVERLORD, "Overlord"));
							break;
						case "Warcryer":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_WARCRY, "Warcryer"));
							break;
						case "BladeDancer":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_B_DANCER, "BladeDancer"));
							break;
						case "SwordSinger":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_S_SINGER, "SwordSinger"));
							break;
						case "Other":
							content = content.replaceAll("%buffs%", getBuffs(Config.CB_SKILLS_OTHER, "Other"));
							break;
					}
					separateAndSend(content, activeChar);
					break;
				case "buff_cb":
					if (condicionFavorite(activeChar, content, Config.ONLY_USE_BUFFER_PEACE_ZONE))
					{
						return;
					}
					
					if (st.hasMoreTokens())
					{
						final int skillId = Integer.parseInt(st.nextToken());
						final int skillLvl = Integer.parseInt(st.nextToken());
						SkillTable.getInstance().getInfo(skillId, skillLvl).getEffects(activeChar, activeChar);// id, lvl
						parseCmd("_bbsgetfav;buffer;" + st.nextToken(), activeChar);
					}
					break;
			}
		}
	}
	
	/**
	 * Obtenemos los buffs de cada clase definidos previamente en los configs
	 * @param config
	 * @param menu
	 * @return
	 */
	private String getBuffs(FastMap<Integer, Integer> config, String menu)
	{
		StringBuilder st = new StringBuilder();
		st.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=600 HEIGHT=62 bgcolor=111111>");
		st.append("<tr>");
		st.append("<td align=center><font name=hs12 color=E95600>" + menu + "</font></td>");
		st.append("</tr>");
		st.append("</table>");
		
		st.append("<table border=0 cellspacing=0 cellpadding=1 WIDTH=600 HEIGHT=62>");
		st.append("<tr>");
		byte cont = 0;
		
		if (!config.isEmpty())
		{
			for (int skillId : config.keySet())
			{
				if (cont == 3)
				{
					st.append("</tr>");
					st.append("</table>");
					st.append("<table border=0 cellspacing=0 cellpadding=1 WIDTH=600 HEIGHT=62>");
					st.append("<tr>");
					cont = 0;
				}
				cont++;
				
				String skillName = SkillTable.getInstance().getInfo(skillId, config.get(skillId)).getName();
				st.append("<td fixwidth=180 height=62 align=center><img src=Icon.skill" + getIconSkill(skillId) + " WIDTH=32 HEIGHT=32><br1><button value=\"" + skillName + " Lvl " + config.get(skillId) + "\" action=\"bypass _bbsgetfav;buff_cb;" + skillId + ";" + config.get(skillId) + ";" + menu + "\" width=180 height=30 back=L2UI_ct1.button_df fore=L2UI_ct1.button_df</td>");
			}
		}
		
		st.append("</tr></table>");
		return st.toString();
	}
	
	/**
	 * Obtenemos el iconos de 1 skill segun su Id
	 * @param id
	 * @return
	 */
	private String getIconSkill(int id)
	{
		if (id == 4)
		{
			return "0004";
		}
		if ((id > 9) && (id < 100))
		{
			return "00" + id;
		}
		if ((id > 99) && (id < 1000))
		{
			return "0" + id;
		}
		if (id == 1517)
		{
			return "1536";
		}
		if (id == 1518)
		{
			return "1537";
		}
		if (id == 1547)
		{
			return "0065";
		}
		if (id == 2076)
		{
			return "0195";
		}
		if ((id > 4550) && (id < 4555))
		{
			return "5739";
		}
		if ((id > 4698) && (id < 4701))
		{
			return "1331";
		}
		if ((id > 4701) && (id < 4704))
		{
			return "1332";
		}
		if (id == 6049)
		{
			return "0094";
		}
		return String.valueOf(id);
	}
	
	/**
	 * Definimos la parte superior del html donde estaran las opciones habilitadas para usarse
	 * @return
	 */
	private String topHtml()
	{
		StringBuilder tb = new StringBuilder();
		tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=40>");
		tb.append("<tr>");
		if (Config.ENABLE_GM_SHOP_CB)
		{
			tb.append("<td FIXWIDTH=256 HEIGHT=32 align=center><button value=\"GM Shop\" action=\"bypass _bbsgetfav;shop\" back=L2UI_CT1.Tab_DF_Tab_Selected fore=L2UI_CT1.Tab_DF_Tab_Unselected WIDTH=130 HEIGHT=32/></td>");
		}
		if (Config.ENABLE_GK_GLOBAL_CB)
		{
			tb.append("<td FIXWIDTH=256 HEIGHT=32 align=center><button value=\"GK Global\" action=\"bypass _bbsgetfav;gk\" back=L2UI_CT1.Tab_DF_Tab_Selected fore=L2UI_CT1.Tab_DF_Tab_Unselected WIDTH=130 HEIGHT=32/></td>");
		}
		if (Config.ENABLE_BUFFER_CB)
		{
			tb.append("<td FIXWIDTH=256 HEIGHT=32 align=center><button value=\"Buffer\" action=\"bypass _bbsgetfav;buffer;Prophet\" back=L2UI_CT1.Tab_DF_Tab_Selected fore=L2UI_CT1.Tab_DF_Tab_Unselected WIDTH=130 HEIGHT=32/></td>");
		}
		if (Config.ENABLE_AUGMENT_CB)
		{
			tb.append("<td FIXWIDTH=256 HEIGHT=32 align=center><button value=\"Augment\" action=\"bypass _bbsgetfav;augment\" back=L2UI_CT1.Tab_DF_Tab_Selected fore=L2UI_CT1.Tab_DF_Tab_Unselected WIDTH=130 HEIGHT=32/></td>");
		}
		if (Config.ENABLE_CLASS_MASTER_CB)
		{
			tb.append("<td FIXWIDTH=256 HEIGHT=32 align=center><button value=\"Class Master\" action=\"bypass _bbsgetfav;class\" back=L2UI_CT1.Tab_DF_Tab_Selected fore=L2UI_CT1.Tab_DF_Tab_Unselected WIDTH=130 HEIGHT=32/></td>");
		}
		tb.append("</tr>");
		tb.append("</table>");
		
		return tb.toString();
	}
	
	/**
	 * Definimos las acciones a seguir por el ClassMaster
	 * @param player
	 * @param level
	 * @return
	 */
	private String classHtmlChangeClass(L2PcInstance player, int level)
	{
		StringBuilder tb = new StringBuilder();
		
		if (!Config.CLASS_MASTER_SETTINGS.isAllowed(level))
		{
			int jobLevel = player.getClassId().level();
			
			tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=700 bgcolor=111111 HEIGHT=50>");
			
			switch (jobLevel)
			{
				case 0:
					if (Config.CLASS_MASTER_SETTINGS.isAllowed(1))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back here when you reached level 20 to change your class</font></td></tr>");
					}
					else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back after your first occupation change.</font></td></tr>");
					}
					else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back after your second occupation change.</font></td></tr>");
					}
					else
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>I can't change your occupation.</font></td></tr>");
					}
					break;
				case 1:
					if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back here when you reached level 40 to change your class.</font></td></tr>");
					}
					else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back after your second occupation change.</font></td></tr>");
					}
					else
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>I can't change your occupation.</font></td></tr>");
					}
					break;
				case 2:
					if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back here when you reached level 76 to change your class.</font></td></tr>");
					}
					else
					{
						tb.append("<tr><td align=center><font name=hs12 color=E95600>I can't change your occupation.</font></td></tr>");
					}
					break;
				case 3:
					tb.append("<tr><td align=center><font name=hs12 color=E95600>There is no class change available for you anymore.</font></td></tr>");
					break;
			}
			tb.append("</table>");
		}
		else
		{
			final ClassId currentClassId = player.getClassId();
			if (currentClassId.level() >= level)
			{
				// "data/html/classmaster/nomore.htm");
				tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=700 bgcolor=111111 HEIGHT=50>");
				tb.append("<tr><td align=center><font name=hs12 color=E95600>Sorry, no more class changes available.</font></td></tr>");
				tb.append("</table>");
			}
			else
			{
				final int minLevel = getMinLevel(currentClassId.level());
				if ((player.getLevel() >= minLevel) || Config.ALLOW_ENTIRE_TREE)
				{
					StringBuilder menu = new StringBuilder(100);
					for (ClassId cid : ClassId.values())
					{
						if ((cid == ClassId.inspector) && (player.getTotalSubClasses() < 2))
						{
							continue;
						}
						if (validateClassId(currentClassId, cid) && (cid.level() == level))
						{
							StringUtil.append(menu, "<button value=\"", classList.get(cid.getId()), "\" action=\"bypass -h _bbsgetfav;change_class;", String.valueOf(cid.getId()), "\" width=250 height=25 back=L2UI_CT1.Button_DF_Down fore=L2UI_CT1.Button_DF>", "<br>");
						}
					}
					
					if (menu.length() > 0)
					{
						tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=50>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Select your class:<br></font></td></tr>");
						tb.append("<tr><td FIXWIDTH=750 align=center>" + menu.toString() + "</td></tr>");
						tb.append("</table>");
						// html.setFile(player.getHtmlPrefix(), "data/html/classmaster/template.htm");
					}
					else
					{
						tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=50>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Sorry, no more class changes available.</font></td></tr>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back here when you reach level " + String.valueOf(getMinLevel(level - 1)) + " to change your class.</font></td></tr>");
						tb.append("</table>");
						// html.setFile(player.getHtmlPrefix(), "data/html/classmaster/comebacklater.htm");
					}
				}
				else
				{
					if (minLevel < Integer.MAX_VALUE)
					{
						tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=50>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Sorry, no more class changes available.</font></td></tr>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Come back here when you reach level " + String.valueOf(getMinLevel(level)) + " to change your class.</font></td></tr>");
						tb.append("</table>");
						// html.setFile(player.getHtmlPrefix(), "data/html/classmaster/comebacklater.htm");
					}
					else
					{
						tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=50>");
						tb.append("<tr><td align=center><font name=hs12 color=E95600>Sorry, no more class changes available.</font></td></tr>");
						tb.append("</table>");
						// "data/html/classmaster/nomore.htm");
					}
				}
			}
		}
		
		return tb.toString();
	}
	
	/**
	 * Definimos el html para el cambio exitoso de clase
	 * @param val
	 * @return
	 */
	private String changeClassOk(int val)
	{
		StringBuilder tb = new StringBuilder();
		tb.append("<table border=0 cellspacing=0 cellpadding=0 WIDTH=750 bgcolor=111111 HEIGHT=50>");
		tb.append("<tr><td align=center><font name=hs12 color=E95600>You have now become a </font><font name=hs12 color=LEVEL>" + classList.get(val) + "</font></td></tr>");
		tb.append("</table>");
		return tb.toString();
	}
	
	// ~ ----------------------------------------- ~ //
	// ~ ------ METODOS Y FUNCIONES VARIAS ------- ~ //
	// ~ ----------------------------------------- ~ //
	
	/**
	 * Teletransportamos al player a las cordenadas especificadas luego de cumplir las condiciones normales<br>
	 * Que el lugar no este bajo siege<br>
	 * Que el player no tenga karma, de ser activado en los configs<br>
	 * Que el player no este muerto.<br>
	 * Que el player no tenga un ward<br>
	 * @param player
	 * @param x
	 * @param y
	 * @param z
	 */
	private final void doTeleport(L2PcInstance player, int x, int y, int z)
	{
		// you cannot teleport to village that is in siege
		if (SiegeManager.getInstance().getSiege(x, y, z) != null)
		{
			// TODO cambiar por html ???
			player.sendMessage("Go away, you're not welcome here.");
			player.sendPacket(SystemMessageId.NO_PORT_THAT_IS_IN_SIGE);
			return;
		}
		if (TownManager.townHasCastleInSiege(x, y) && player.isInsideZone(ZoneId.TOWN))
		{
			// TODO cambiar por html ???
			player.sendMessage("Go away, you're not welcome here.");
			player.sendPacket(SystemMessageId.NO_PORT_THAT_IS_IN_SIGE);
			return;
		}
		if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getKarma() > 0)) // karma
		{
			// TODO cambiar por html ???
			player.sendMessage("Go away, you're not welcome here.");
			return;
		}
		if (player.isCombatFlagEquipped())
		{
			// TODO cambiar por html ???
			player.sendMessage("Go away, you're not welcome here.");
			player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
			return;
		}
		if (player.isAlikeDead())
		{
			return;
		}
		
		player.teleToLocation(x, y, z, true);
		
		player.sendPacket(ActionFailed.STATIC_PACKET);
	}
	
	/**
	 * @param level - current skillId level (0 - start, 1 - first, etc)
	 * @return minimum player level required for next class transfer
	 */
	private final int getMinLevel(int level)
	{
		switch (level)
		{
			case 0:
				return 20;
			case 1:
				return 40;
			case 2:
				return 76;
			default:
				return Integer.MAX_VALUE;
		}
	}
	
	/**
	 * Returns true if class change is possible
	 * @param oldCID current player ClassId
	 * @param newCID new ClassId
	 * @return true if class change is possible
	 */
	private final boolean validateClassId(ClassId oldCID, ClassId newCID)
	{
		if ((newCID == null) || (newCID.getRace() == null))
		{
			return false;
		}
		
		if (oldCID.equals(newCID.getParent()))
		{
			return true;
		}
		
		if (Config.ALLOW_ENTIRE_TREE && newCID.childOf(oldCID))
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * Returns true if class change is possible
	 * @param oldCID current player ClassId
	 * @param val new class index
	 * @return
	 */
	private final boolean validateClassId(ClassId oldCID, int val)
	{
		try
		{
			return validateClassId(oldCID, ClassId.getClassId(val));
		}
		catch (Exception e)
		{
			// possible ArrayOutOfBoundsException
		}
		return false;
	}
	
	/**
	 * @param player
	 * @param val
	 * @return
	 */
	private final boolean checkAndChangeClass(L2PcInstance player, int val)
	{
		if ((getMinLevel(player.getClassId().level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
		{
			return false;
		}
		
		if (!validateClassId(player.getClassId(), val))
		{
			return false;
		}
		
		int newJobLevel = player.getClassId().level() + 1;
		
		// Weight/Inventory check
		if (!Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).isEmpty() && !player.isInventoryUnder90(false))
		{
			player.sendPacket(SystemMessageId.INVENTORY_LESS_THAN_80_PERCENT);
			return false;
		}
		
		// check if player have all required items for class transfer
		for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keySet())
		{
			int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
			if (player.getInventory().getInventoryItemCount(_itemId, -1) < _count)
			{
				player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
				return false;
			}
		}
		
		// get all required items for class transfer
		for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).keySet())
		{
			int _count = Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel).get(_itemId);
			if (!player.destroyItemByItemId("ClassMaster", _itemId, _count, player, true))
			{
				return false;
			}
		}
		
		// reward player with items
		for (int _itemId : Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).keySet())
		{
			final int _count = Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).get(_itemId);
			player.addItem("ClassMaster", _itemId, _count, player, true);
		}
		
		player.setClassId(val);
		
		if (player.isSubClassActive())
		{
			player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
		}
		else
		{
			player.setBaseClass(player.getActiveClass());
		}
		
		player.broadcastUserInfo();
		
		return true;
	}
	
	/**
	 * Condiciones generales de uso de las diferentes opciones de la pestaña favorite
	 * @param activeChar
	 * @param content
	 * @param opcion
	 * @return
	 */
	private final boolean condicionFavorite(L2PcInstance activeChar, String content, boolean opcion)
	{
		if (!activeChar.isGM())
		{
			if (!activeChar.isInsideZone(ZoneId.PEACE) && opcion)
			{
				final String outPeaceZoneHtml = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/custom/favorite/outPeaceZoneHtml.htm");
				content = content.replaceAll("%body%", outPeaceZoneHtml);
				separateAndSend(content, activeChar);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Creamos la lista de clases q nos permitira identificar cada clase por su Id.
	 */
	private final void createClassList()
	{
		classList = new HashMap<>();
		classList.put(0, "Fighter");
		classList.put(1, "Warrior");
		classList.put(2, "Gladiator");
		classList.put(3, "Warlord");
		classList.put(4, "Knight");
		classList.put(5, "Paladin");
		classList.put(6, "Dark Avenger");
		classList.put(7, "Rogue");
		classList.put(8, "Treasure Hunter");
		classList.put(9, "Hawkeye");
		classList.put(10, "Mage");
		classList.put(11, "Wizard");
		classList.put(12, "Sorcerer");
		classList.put(13, "Necromancer");
		classList.put(14, "Warlock");
		classList.put(15, "Cleric");
		classList.put(16, "Bishop");
		classList.put(17, "Prophet");
		classList.put(18, "Elven Fighter");
		classList.put(19, "Elven Knight");
		classList.put(20, "Temple Knight");
		classList.put(21, "Swordsinger");
		classList.put(22, "Elven Scout");
		classList.put(23, "Plains Walker");
		classList.put(24, "Silver Ranger");
		classList.put(25, "Elven Mage");
		classList.put(26, "Elven Wizard");
		classList.put(27, "Spellsinger");
		classList.put(28, "Elemental Summoner");
		classList.put(29, "Oracle");
		classList.put(30, "Elder");
		classList.put(31, "Dark Fighter");
		classList.put(32, "Palus Knightr");
		classList.put(33, "Shillien Knight");
		classList.put(34, "Bladedancer");
		classList.put(35, "Assasin");
		classList.put(36, "Abyss Walker");
		classList.put(37, "Phantom Ranger");
		classList.put(38, "Dark Mage");
		classList.put(39, "Dark Wizard");
		classList.put(40, "Spellhowler");
		classList.put(41, "Phantom Summoner");
		classList.put(42, "Shillien Oracle");
		classList.put(43, "Shilien Elder");
		classList.put(44, "Orc Fighter");
		classList.put(45, "Orc Raider");
		classList.put(46, "Destroyer");
		classList.put(47, "Orc Monk");
		classList.put(48, "Tyrant");
		classList.put(49, "Orc Mage");
		classList.put(50, "Orc Shaman");
		classList.put(51, "Overlord");
		classList.put(52, "Warcryer");
		classList.put(53, "Dwarven Fighter");
		classList.put(54, "Scavenger");
		classList.put(55, "Bounty Hunter");
		classList.put(56, "Artisan");
		classList.put(57, "Warsmith");
		classList.put(88, "Duelist");
		classList.put(89, "Dreadnought");
		classList.put(90, "Phoenix Knight");
		classList.put(91, "Hell Knight");
		classList.put(92, "Sagittarius");
		classList.put(93, "Adventurer");
		classList.put(94, "Archmage");
		classList.put(95, "Soultaker");
		classList.put(96, "Arcana Lord");
		classList.put(97, "Cardinal");
		classList.put(98, "Hierophant");
		classList.put(99, "Evas Templar");
		classList.put(100, "Sword Muse");
		classList.put(101, "Wind Rider");
		classList.put(102, "Moonlight Sentinel");
		classList.put(103, "Mystic Muse");
		classList.put(104, "Elemental Master");
		classList.put(105, "Evas Saint");
		classList.put(106, "Shillien Templar");
		classList.put(107, "Spectral Dancer");
		classList.put(108, "Ghost Hunter");
		classList.put(109, "Ghost Sentinel");
		classList.put(110, "Storm Screamer");
		classList.put(111, "Spectral Master");
		classList.put(112, "Shillien Saint");
		classList.put(113, "Titan");
		classList.put(114, "Grand Khavatari");
		classList.put(115, "Dominator");
		classList.put(116, "Doomcryer");
		classList.put(117, "Fortune Seeker");
		classList.put(118, "Maestro");
		classList.put(123, "Male Soldier");
		classList.put(124, "Female Soldier");
		classList.put(125, "Trooper");
		classList.put(126, "Warder");
		classList.put(127, "Berserker");
		classList.put(128, "Male Soulbreaker");
		classList.put(129, "Female Soulbreaker");
		classList.put(130, "Arbalester");
		classList.put(131, "Doombringer");
		classList.put(132, "Male Soulhound");
		classList.put(133, "Female Soulhound");
		classList.put(134, "Trickster");
		classList.put(135, "Inspector");
		classList.put(136, "Judicator");
	}
	
	@Override
	public void parseWrite(String ar1, String ar2, String ar3, String ar4, String ar5, L2PcInstance activeChar)
	{
		// TODO Auto-generated method stub
	}
	
	public static FavoriteBBSManager getInstance()
	{
		return SingletonHolder._instance;
	}
	
	private static class SingletonHolder
	{
		protected static final FavoriteBBSManager _instance = new FavoriteBBSManager();
	}
}